package com.example.test.comutil;

import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.media.ThumbnailUtils;
import android.os.Build;
import android.util.Base64;
import android.view.View;

import androidx.annotation.RequiresApi;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class BitmapUtils {

    /**
     * 灰白图片抖动算法
     *
     * @param img 原Bitmap
     * @return 新的Bitmap
     */
    public static Bitmap convertGreyImgByFloyd(Bitmap img) {
        int width = img.getWidth();//获取位图的宽  
        int height = img.getHeight();//获取位图的高  
        int[] pixels = new int[width * height]; //通过位图的大小创建像素点数组  
        img.getPixels(pixels, 0, width, 0, 0, width, height);
        int[] gray = new int[height * width];
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int grey = pixels[width * i + j];
                int red = ((grey & 0x00FF0000) >> 16);
                gray[width * i + j] = red;
            }
        }
        int e = 0;
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int g = gray[width * i + j];
                if (g >= 128) {
                    pixels[width * i + j] = 0xffffffff;
                    e = g - 255;
                } else {
                    pixels[width * i + j] = 0xff000000;
                    e = g - 0;
                }
                if (j < width - 1 && i < height - 1) {
                    //右边像素处理
                    gray[width * i + j + 1] += 3 * e / 8;
                    //下
                    gray[width * (i + 1) + j] += 3 * e / 8;
                    //右下
                    gray[width * (i + 1) + j + 1] += e / 4;
                } else if (j == width - 1 && i < height - 1) {//靠右或靠下边的像素的情况
                    // 下方像素处理
                    gray[width * (i + 1) + j] += 3 * e / 8;
                } else if (j < width - 1 && i == height - 1) {//右边像素处理
                    gray[width * (i) + j + 1] += e / 4;
                }
            }
        }
        Bitmap mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        mBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
        return mBitmap;
    }


    /**
     * 转为二值图像
     *
     * @param bmp 原图bitmap
     * @param w   转换后的宽
     * @param h   转换后的高
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.FROYO)
    public static Bitmap convertToBMW(Bitmap bmp, int w, int h, int tmp) {
        int width = bmp.getWidth(); // 获取位图的宽
        int height = bmp.getHeight(); // 获取位图的高
        int[] pixels = new int[width * height]; // 通过位图的大小创建像素点数组
        // 设定二值化的域值，默认值为100
        //tmp = 180;
        bmp.getPixels(pixels, 0, width, 0, 0, width, height);
        //灰色
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int grey = pixels[width * i + j];
                int alpha = Color.alpha(grey);
                int red = Color.red(grey);
                int green = Color.green(grey);
                int blue = Color.blue(grey);
                if (red > tmp) {
                    red = 255;
                } else {
                    red = 0;
                }
                if (blue > tmp) {
                    blue = 255;
                } else {
                    blue = 0;
                }
                if (green > tmp) {
                    green = 255;
                } else {
                    green = 0;
                }
                grey = (int) ((float) red * 0.3 + (float) green * 0.59 + (float) blue * 0.11);
                grey = (alpha << 24) | (grey << 16) | (grey << 8) | grey;
                pixels[width * i + j] = grey;
            }
        }
        if (width <= 0) {
            width = 1;
        }
        if (height <= 0) {
            height = 1;
        }
        // 新建图片
        Bitmap newBmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        // 设置图片数据
        newBmp.setPixels(pixels, 0, width, 0, 0, width, height);
        Bitmap resizeBmp = ThumbnailUtils.extractThumbnail(newBmp, w, h);
        return resizeBmp;
    }

    /***
     * 图片去色,返回灰度图片
     * @param bmp 传入的图片
     * @return 去色后的图片
     */
    public static Bitmap toGrayscale(Bitmap bmp) {
        int width = bmp.getWidth(); // 获取位图的宽
        int height = bmp.getHeight(); // 获取位图的高
        int[] pixels = new int[width * height]; // 通过位图的大小创建像素点数组
        // 设定二值化的域值，默认值为100
        //tmp = 180;
        bmp.getPixels(pixels, 0, width, 0, 0, width, height);
        //灰色
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int grey = pixels[width * i + j];
                int alpha = Color.alpha(grey);
                int red = Color.red(grey);
                int green = Color.green(grey);
                int blue = Color.blue(grey);
                grey = (int) (0.299 * (double) red + 0.587 * (double) green + 0.114 * (double) blue);
                grey = (alpha << 24) | (grey << 16) | (grey << 8) | grey;
                pixels[width * i + j] = grey;
            }
        }
        if (width <= 0) {
            width = 1;
        }
        if (height <= 0) {
            height = 1;
        }
        // 新建图片
        Bitmap newBmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        // 设置图片数据
        newBmp.setPixels(pixels, 0, width, 0, 0, width, height);
        Bitmap resizeBmp = ThumbnailUtils.extractThumbnail(newBmp, width, height);
        return resizeBmp;
    }


    /**
     * 保存图片到本地
     *
     * @param bitmap
     */
    @RequiresApi(api = Build.VERSION_CODES.FROYO)
    public static File saveBitmapFile(Bitmap bitmap, String fileName) {
        //        //File file = new File(Environment.getExternalStorageDirectory() + "/" + fileName);
        File file = new File(LeoUtils.getApplication().getExternalFilesDir(null) + "/" + fileName);
        if (file.exists()) {
            file.delete();
        }
        try {
            FileOutputStream fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
            fos.flush();
            fos.close();
            LogUtils.i("bit", "保存成功");
            return file;
        } catch (FileNotFoundException e) {
            LogUtils.i("bit", "e:" + e);
            e.printStackTrace();
        } catch (IOException e) {
            LogUtils.i("bit", "e2:" + e);
            e.printStackTrace();
        }
        return null;
    }

    public static Bitmap convertViewToBitmap(View view) {
        view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
        view.buildDrawingCache();
        Bitmap bitmap = view.getDrawingCache();
        return bitmap;
    }


    public static Bitmap getBitmapFromView(View v) {
        Bitmap b = null;
        if (v.getWidth() > 0 && v.getHeight() > 0) {
            b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);//图片压缩处理2字节
            Canvas c = new Canvas(b);
            v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
            // Draw background
            Drawable bgDrawable = v.getBackground();
            if (bgDrawable != null) {
                bgDrawable.draw(c);
            } else {
                c.drawColor(Color.WHITE);
            }
            // Draw view to canvas
            v.draw(c);
        }
        return b;
    }

    public static Bitmap verticalMosaicPictures(Bitmap bmp1, Bitmap bmp2) {
        return verticalMosaicPictures(bmp1, bmp2, null);
    }

    /**
     * 垂直拼接图片
     *
     * @param bmp1
     * @param bmp2
     * @return
     */
    public static Bitmap verticalMosaicPictures(Bitmap bmp1, Bitmap bmp2, Bitmap bg) {
        Bitmap retBmp;
        int width = bmp1.getWidth();
        if (bmp2.getWidth() != width) {
            //以第一张图片的宽度为标准，对第二张图片进行缩放。
            int h2 = bmp2.getHeight() * width / bmp2.getWidth();
            retBmp = Bitmap.createBitmap(width, bmp1.getHeight() + h2, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(retBmp);
            if (bg != null) {
                canvas.drawBitmap(BitmapUtils.resizeBitmap(bg, retBmp.getWidth(), retBmp.getHeight()), 0, 0, null);
            }
            Bitmap newSizeBmp2 = resizeBitmap(bmp2, width, h2);
            canvas.drawBitmap(bmp1, 0, 0, null);
            canvas.drawBitmap(newSizeBmp2, 0, bmp1.getHeight(), null);
        } else {
            //两张图片宽度相等，则直接拼接。
            retBmp = Bitmap.createBitmap(width, bmp1.getHeight() + bmp2.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(retBmp);
            if (bg != null) {
                canvas.drawBitmap(BitmapUtils.resizeBitmap(bg, retBmp.getWidth(), retBmp.getHeight()), 0, 0, null);
            }
            canvas.drawBitmap(bmp1, 0, 0, null);
            canvas.drawBitmap(bmp2, 0, bmp1.getHeight(), null);
        }
        return retBmp;
    }

    public static Bitmap levelMosaicPictures(Bitmap bmp1, Bitmap bmp2) {
        return levelMosaicPictures(bmp1, bmp2, null);
    }

    /**
     * 水平拼接图片
     *
     * @param bmp1
     * @param bmp2
     * @return
     */
    public static Bitmap levelMosaicPictures(Bitmap bmp1, Bitmap bmp2, Bitmap bg) {
        Bitmap retBmp;
        int height = bmp1.getHeight();
        if (bmp2.getHeight() != height) {
            //以第一张图片的宽度为标准，对第二张图片进行缩放。
            int w2 = bmp2.getWidth() * height / bmp2.getHeight();
            retBmp = Bitmap.createBitmap(bmp1.getWidth() + w2, height, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(retBmp);
            if (bg != null) {
                canvas.drawBitmap(BitmapUtils.resizeBitmap(bg, retBmp.getWidth(), retBmp.getHeight()), 0, 0, null);
            }
            Bitmap newSizeBmp2 = resizeBitmap(bmp2, w2, height);
            canvas.drawBitmap(bmp1, 0, 0, null);
            canvas.drawBitmap(newSizeBmp2, bmp1.getWidth(), 0, null);
        } else {
            //两张图片宽度相等，则直接拼接。
            retBmp = Bitmap.createBitmap(bmp1.getWidth() + bmp2.getWidth(), height, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(retBmp);
            if (bg != null) {
                canvas.drawBitmap(BitmapUtils.resizeBitmap(bg, retBmp.getWidth(), retBmp.getHeight()), 0, 0, null);
            }
            canvas.drawBitmap(bmp1, 0, 0, null);
            canvas.drawBitmap(bmp2, bmp1.getWidth(), 0, null);
        }
        return retBmp;
    }

    /**
     * 旋转
     *
     * @param bitmap
     * @return
     */
    public static Bitmap  rotatingPicture(Bitmap bitmap, int angle) {
        Matrix matrix = new Matrix();
        matrix.setRotate(angle, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    }

    /**
     * 裁剪
     *
     * @param bitmap 原图
     * @return 裁剪后的图像
     */
    private Bitmap cropBitmap(Bitmap bitmap) {
        int w = bitmap.getWidth(); // 得到图片的宽，高
        int h = bitmap.getHeight();
        int cropWidth = w >= h ? h : w;// 裁切后所取的正方形区域边长
        cropWidth /= 2;
        int cropHeight = (int) (cropWidth / 1.2);
        return Bitmap.createBitmap(bitmap, w / 3, 0, cropWidth, cropHeight, null, false);
    }

    /**
     * 裁剪
     */
    public static Bitmap cropBitmap(Bitmap bitmap, int cw, int ch) {
        int x = (bitmap.getWidth() - cw) / 2; // 得到图片的宽，高
        int y = (bitmap.getHeight() - ch) / 2;
        return Bitmap.createBitmap(bitmap, x, y, cw, ch, null, false);
    }


    /**
     * 缩放图片
     *
     * @param bitmap    原图片
     * @param newWidth  目标宽度
     * @param newHeight 目标高度
     * @return 目标图片
     */
    public static Bitmap resizeBitmap(Bitmap bitmap, int newWidth, int newHeight) {
        float scaleWidth = ((float) newWidth) / bitmap.getWidth();
        float scaleHeight = ((float) newHeight) / bitmap.getHeight();
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap bmpScale = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return bmpScale;
    }

    public static Bitmap resizeBitmap2(Bitmap bitmap, float scalex, float scaley) {
        Matrix matrix = new Matrix();
        matrix.postScale(scalex, scaley);
        Bitmap bmpScale = Bitmap.createBitmap(bitmap, 0, 0, (int) bitmap.getWidth(), (int) bitmap.getHeight(), matrix, true);
        return bmpScale;
    }

    /**
     * 等比例缩放图片
     *
     * @param bitmap    原图片
     * @param dstWidth  目标宽度
     * @param dstHeight 目标高度
     * @return 目标图片
     */
    public static Bitmap scaleBitmap(Bitmap bitmap, int dstWidth, int dstHeight) {

        //取得图片和图片所处空间的比例
        float scaleBitmap = ((float) bitmap.getWidth()) / bitmap.getHeight();
        float scaleView = ((float) dstWidth) / dstHeight;

        // 空间的大小 / bitmap 的大小 = bitmap 缩放的倍数
        float scaleWidth = ((float) dstWidth) / bitmap.getWidth();
        float scaleHeight = ((float) dstHeight) / bitmap.getHeight();

        Matrix matrix = new Matrix();
//按照比例选择缩放参照
        if (scaleBitmap < scaleView) {
            //比例小于视框时，全部按照图片高度和视框高度的比例进行缩放
            matrix.postScale(scaleHeight, scaleHeight);
        } else {
            //比例大于视框时，全部按照图片宽度和视框宽度的比例进行缩放
            matrix.postScale(scaleWidth, scaleWidth);
        }

        bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return bitmap;
    }


    /**
     * bitmap转为base64压缩处理
     *
     * @param bitmap
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.FROYO)
    public static String bitmapToBase64Label(Bitmap bitmap) {

        Bitmap bm;
        String result = null;
        ByteArrayOutputStream baos = null;
        try {
            if (bitmap != null) {
                baos = new ByteArrayOutputStream();
                bm = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth() / 7, bitmap.getHeight() / 7, true);//图片宽和高压缩
                bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
                baos.flush();
                baos.close();

                byte[] bitmapBytes = baos.toByteArray();
                result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.flush();
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }


    /**
     * base64转为bitmap
     *
     * @param base64Data
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.FROYO)
    public static Bitmap base64ToBitmapLabel(String base64Data) {
        byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);
        Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        return Bitmap.createScaledBitmap(bitmap, bitmap.getWidth() * 7, bitmap.getHeight() * 7, true);//图片宽和高压缩

    }

    /**
     * bitmap转为base64
     *
     * @param bitmap
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.FROYO)
    public static String bitmapToBase64(Bitmap bitmap) {

        String result = null;
        ByteArrayOutputStream baos = null;
        try {
            if (bitmap != null) {
                baos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
                baos.flush();
                baos.close();
                byte[] bitmapBytes = baos.toByteArray();
                result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.flush();
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * base64转为bitmap
     *
     * @param base64Data
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.FROYO)
    public static Bitmap base64ToBitmap(String base64Data) {
        try {
            byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);
            return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        } catch (Exception e) {
            e.printStackTrace();
            return Bitmap.createBitmap(20, 20, Bitmap.Config.ARGB_8888);
        }

    }

    /**
     * 图片放缩
     *
     * @param bitmap 原始的Bitmap
     * @param width  目标宽度
     * @param height 目标高度
     * @return 缩放后的Bitmap
     */
    public static Bitmap scaleMatrix(Bitmap bitmap, float width, float height) {
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        float scaleW = width / w;
        float scaleH = height / h;
        Matrix matrix = new Matrix();
        matrix.postScale(scaleW, scaleH); // 长和宽放大缩小的比例
        return Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);
    }

    /**
     * 手动测量摆放View
     * 对于手动 inflate 或者其他方式代码生成加载的View进行测量，避免该View无尺寸
     *
     * @param v
     * @param width
     * @param height
     */
    public static void layoutView(View v, int width, int height) {
        // validate view.width and view.height
        v.layout(0, 0, width, height);
        int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
        int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);
        v.measure(measuredWidth, measuredHeight);
        v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
    }

    /**
     * 获取一个 View 的缓存视图
     * (前提是这个View已经渲染完成显示在页面上)
     *
     * @param view
     * @return
     */
    @SuppressLint("NewApi")
    public static Bitmap getCacheBitmapFromView(View view) {
        final boolean drawingCacheEnabled = true;
        view.setDrawingCacheEnabled(drawingCacheEnabled);
        view.buildDrawingCache(drawingCacheEnabled);
        final Bitmap drawingCache = view.getDrawingCache();
        Bitmap bitmap;
        if (drawingCache != null) {
            bitmap = Bitmap.createBitmap(drawingCache);
            view.setDrawingCacheEnabled(false);
        } else {
            bitmap = null;
        }
        return bitmap;
    }

    public static int getBitmapSize(Bitmap bitmap) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {    //API 19
            return bitmap.getAllocationByteCount();
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {//API 12
            return bitmap.getByteCount();
        }
        // 在低版本中用一行的字节x高度
        return bitmap.getRowBytes() * bitmap.getHeight();                //earlier version
    }

    ///设置图片白底
    public static Bitmap setWhiteBackground(Bitmap orginBitmap) {
        Paint paint = new Paint();
        Bitmap bitmap = Bitmap.createBitmap(orginBitmap.getWidth(),
                orginBitmap.getHeight(), orginBitmap.getConfig());
        Canvas canvas = new Canvas(bitmap);
        canvas.drawColor(Color.WHITE);
        canvas.drawBitmap(orginBitmap, 0, 0, paint);
        return bitmap;

    }

    //更换颜色
    public static Bitmap convertBitmap(Bitmap bitmap, int color1, int color2) {
        Bitmap mBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
        int mBitmapWidth = mBitmap.getWidth();
        int mBitmapHeight = mBitmap.getHeight();
        int mArrayColorLengh = mBitmapWidth * mBitmapHeight;
        int[] mArrayColor = new int[mArrayColorLengh];
        int count = 0;
        for (int i = 0; i < mBitmapHeight; i++) {
            for (int j = 0; j < mBitmapWidth; j++) {
                int color = mBitmap.getPixel(j, i);
                if (color == color1) {
                    mBitmap.setPixel(j, i, color2);
                }
            }
        }
        return mBitmap;
    }
}
